<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #createCode {
      user-select: none;
    }

    .arr {
      font-size: 12px;
      color: red;
    }
  </style>
</head>

<body>
  <div class="box">
    <p>
      <label for="">用户名:</label>
      <input type="text" id="user">
      <span id="user_span"></span>
    </p>
    <p>
      <label for="">密&emsp;码:</label>
      <input type="password" id="pwd">
      <span id="pwd_span"></span>
    </p>
    <p>
      <label for="">手机号:</label>
      <input type="password" id="phone">
      <span id="phone_span"></span>
    </p>
    <p>
      <label for="">邮&emsp;箱:</label>
      <input type="password" id="email">
      <span id="email_span"></span>
    </p>
    <p>
      <label for="">验证码:</label>
      <input type="text" id="code">
      <span id="createCode">a1b2</span>
      <span id="code_span"></span>
    </p>
    <p>
      <input id="btn" type="submit" value="注册">
    </p>
  </div>
</body>
<script>
     // 用户名
    // 由数字 大小写字母 _ $ 组成 , 6-12位,且不能以数字开头

    // 判断的流程  从易到难的顺序 
    // a. 长度  6-12位 
    // b. 不能以数字开头
    // c. 由数字 大小写字母 _ $ 组成  (所有的字符都必须在合法字符的范围内,只要有一个不是合法的字符 报错   => 判断字符串中是否能含有非法字符)


    // 密码
    // 由数字 大小写字母 _    6-12位 

    // 判断密码强度
    // 数字,大写,小写,特殊字符  中 只出现一种   11111   aaaaaa  AAAAAA   弱
    // 数字,大写,小写,特殊字符  中 出现2种      11111a  A1111   aAAAAA   中
    // 数字,大写,小写,特殊字符  中 出现3种      1aA                      强
    // 数字,大写,小写,特殊字符  中 出现4种      1aA_                     超强

    // 是否存在数字  / 大写 /小写 / 特殊字符

    // true + true + true + false  => 3 

    // 确认密码  
    // 和密码相同  

    // 验证码  => 封装一个方法可以随机生成四位验证码 (0-9 a-z A-Z )
    // 1. 页面加载时,随机生成四个不重复的验证码 (0-9 a-z A-Z )   => createCode
    // 2. 点击 验证码 进行切换
    // 3. 验证码输入判断  (输入的  随机生成的  保持一致) 
</script>
<script>

  // 得到一个合法字符的数组(数字 大小写字母 下划线)
  var numList = [];
  for (var i = 48; i <= 57; i++) {
    var char = String.fromCharCode(i); //根据编码返回对应的字符
    numList.push(char);
  }
  console.log(numList);

  var smallList = [];
  for (var i = 97; i <= 122; i++) {
    var char = String.fromCharCode(i); //根据编码返回对应的字符
    smallList.push(char);
  }
  console.log(smallList);

  var bigList = [];
  for (var i = 65; i <= 90; i++) {
    var char = String.fromCharCode(i); //根据编码返回对应的字符
    bigList.push(char);
  }
  console.log(bigList);

  var speList = ["_"];// 允许使用的特殊字符的集合

  var normalList = numList.concat(smallList, bigList, speList);
  console.log(normalList);


  function randCode(len) {
    len = len == undefined ? 4 : len;  //默认值(4)

    var list = numList.concat(smallList, bigList);
    var arr = [];
    for (var i = 0; i < len; i++) {  // 假如 i=2时 随机元素重复
      var index = Math.round(Math.random() * (list.length - 1));
      var item = list[index];
      if (arr.indexOf(item) == -1) {  // 不存在  => 放
        arr.push(item);   //把随机的元素放到数组中
      } else { // 存在   => 如果不做任何操作 会少放一次
        //  => 假如 i=2时 随机元素重复 i-- => i=1  本次循环结束  i++ => i=2 (忽略本次,再来一次)
        i--;  // i--   
      }
    }
    console.log(arr);

    return arr.join("");

  }


  // 1. JS操作元素之前必须先获取元素
  var userInp = document.getElementById("user");
  var userSpan = document.getElementById("user_span");
  var pwdInp = document.getElementById("pwd");
  var pwdSpan = document.getElementById("pwd_span");
  // var repwdInp = document.getElementById("repwd");
  // var repwdSpan = document.getElementById("repwd_span");
  var phoneInp = document.getElementById("phone");
  var phoneSpan = document.getElementById("phone_span");
  var emailInp = document.getElementById("email");
  var emailSpan = document.getElementById("email_span");
  var codeInp = document.getElementById("code");
  var codeSpan = document.getElementById("code_span");
  var createCode = document.getElementById("createCode");

  var regBtn = document.getElementById("btn");

  var isUserOk = false;
  var isPwdOk = false;
  var isPhoneOk = false;
  var isEmailOk = false;
  var isCodeOk = false;

  createCode.innerText = randCode();
  createCode.onclick = function () {
    createCode.innerText = randCode();
  }


  // 用户名验证
  // a. 长度  6-12位 
  // b. 不能以数字开头
  // c. 由数字 大小写字母 _ $ 组成
  user.onchange = function () {
    var user = userInp.value;  //表单元素的取值(字符串)
    var userReg = /^[a-zA-Z_][\w$]{5,11}$/;

    if (userReg.test(user)) {
      userSpan.innerText = "√";
      userSpan.style.fontSize = "12px";
      userSpan.style.color = "green";
      isUserOk = true;
    } else {
      userSpan.innerText = "由数字 大小写字母 _ $ 组成 , 6-12位,且不能以数字开头";
      userSpan.className = 'arr';
    }
  }



  // 密码
  // 由数字 大小写字母 _    6-12位 

  // 判断密码强度
  // 数字,大写,小写,特殊字符  中 只出现一种   11111   aaaaaa  AAAAAA   弱
  // 数字,大写,小写,特殊字符  中 出现2种      11111a  A1111   aAAAAA   中
  // 数字,大写,小写,特殊字符  中 出现3种      1aA                      强
  // 数字,大写,小写,特殊字符  中 出现4种      1aA_                     超强

  pwd.onchange = function () {
    var pwd = pwdInp.value;
    var pwdReg = /^[\w$]{6,12}$/;
    isPwdOk = false;

    if (pwdReg.test(pwd)) {
      pwdSpan.innerText = "√";
      pwdSpan.style.color = "gold";

      var isExistNum = false;
      var isExistSmall = false;
      var isExistBig = false;
      var isExistSpe = false;

      if (/[0-9]/.test(pwd)) isExistNum = true;
      if (/[a-z]/.test(pwd)) isExistSmall = true;
      if (/[A-Z]/.test(pwd)) isExistBig = true;
      if (/[_$]/.test(pwd)) isExistSpe = true;

      // var isExistNum = /[0-9]/.test(pwd) ? true :false;

      var sum = isExistNum + isExistSmall + isExistBig + isExistSpe;

      //  true + true + false

      switch (sum) {
        case 1:
          pwdSpan.innerText = "密码强度:弱";
          pwdSpan.style.color = "green";
          break;
        case 2:
          pwdSpan.innerText = "密码强度:中";
          pwdSpan.style.color = "orange";
          break;
        case 3:
          pwdSpan.innerText = "密码强度:强";
          pwdSpan.style.color = "yellow";
          break;
        case 4:
          pwdSpan.innerText = "密码强度:超强";
          pwdSpan.style.color = "gold";
          break;
      }

      isPwdOk = true;

    } else {
      pwdSpan.innerText = "密码由数字,大小写字母,下划线组成";
      pwdSpan.className = 'arr'
    }
  }



  phone.onchange = function () {
    isPhoneOk = false;
    var phone = phoneInp.value;
    var phoneReg = /^1[3-9]\d{9}$/;

    if (phoneReg.test(phone)) {
      phoneSpan.innerText = "√";
      phoneSpan.style.color = "gold";
    } else {
      phoneSpan.innerText = "请输入有效号码";
      phoneSpan.className = 'arr';
    }
  }

  email.onchange = function () {
    isEmailOk = false;
    var email = emailInp.value;
    var emailReg = /^\w{6,20}@\w{2,10}(\.com|\.cn|\.net|\.email)$/;

    if (emailReg.test(email)) {
      emailSpan.innerText = "√";
      emailSpan.style.color = "gold";
    } else {
      emailSpan.innerText = "邮箱由数字,大小写字母,下划线组成";
      emailSpan.className = 'arr';
    }
  }

  code.onchange = function () {
    isCodeOk = false;
    var code = codeInp.value;
    var Rcode = createCode.innerText;  //随机验证码
    var codeReg = new RegExp(Rcode, 'i');


    if (codeReg.test(code)) {
      codeSpan.innerText = "√";
      codeSpan.style.color = "gold";
      createCode.style.display = 'none'
    } else {
      codeSpan.innerText = "请输入正确验证码";
      codeSpan.className = 'arr';
    }
  }


  regBtn.onclick = function () {
    if (isUserOk && isPwdOk && isPhoneOk && isEmailOk && isCodeOk) {
      alert("注册成功");
    }
  }





</script>


</html>